<template>
  <SearchBar
    ref="searchRef"
    :placeholder="$t('staff_list.search_keyword')"
    
    v-model="formData"
    @search-event="val => handleSearchEvent(val)"
  >
    <template #footer>
      <el-button v-auth="{ authArr: props.auth, key: 'add' }" type="primary" @click="emit('add')">
        {{ $t("staff_list.add_new_employees") }}
      </el-button>
    </template>
    <template #searchForm="searchProp">
      <div class="modal-content">
        <div class="modal-title">
          <!-- {{ $t("merak.search_list_ad") }} -->
        </div>
        <div class="modal—body">
          <el-scrollbar class="search_from_scrollbar">
            <div class="scrollbar-content">
              <SelectedParams v-model="formData" />
              <el-form ref="formRef" label-position="top" :model="formValue" :rules="formRules">
                <MerakColapse :is-active="false">
                  <template #header>{{ $t("staff_list.personal_info") }}</template>
                  <el-row :gutter="40">
                    <template v-for="item of formItems.user">
                      <el-col v-if="item.visible !== false" :span="span">
                        <MerakXFormItem
                          v-bind="item"
                          :label="$t(`staff_list.${item.prop}`)"
                          :query-options="field => queryOptions(field)"
                          v-model:value="formValue[item.prop]"
                          v-model:default="formValue[`${item.prop}_txt`]"
                          v-model:ingoreQuery="state.ignoreQuery"
                          @change="params => handleFormItemChange(params)"
                        />
                      </el-col>
                    </template>
                  </el-row>
                </MerakColapse>
                <MerakColapse :is-active="false">
                  <template #header>{{ $t("staff_list.newsletter_info") }}</template>
                  <el-row :gutter="40">
                    <el-col v-for="item of formItems.newsletter" :span="span">
                      <MerakXFormItem
                        v-bind="item"
                        :label="$t(`staff_list.${item.prop}`)"
                        :query-options="field => queryOptions(field)"
                        v-model:value="formValue[item.prop]"
                        v-model:default="formValue[`${item.prop}_txt`]"
                        v-model:ingoreQuery="state.ignoreQuery"
                        @change="params => handleFormItemChange(params)"
                      />
                    </el-col>
                  </el-row>
                </MerakColapse>
                <MerakColapse :is-active="false">
                  <template #header>{{ $t("staff_list.education_info") }}</template>
                  <el-row :gutter="40">
                    <el-col v-for="item of formItems.education" :span="span">
                      <MerakXFormItem
                        v-bind="item"
                        :label="$t(`staff_list.${item.prop}`)"
                        :query-options="field => queryOptions(field)"
                        v-model:value="formValue[item.prop]"
                        v-model:default="formValue[`${item.prop}_txt`]"
                        v-model:ingoreQuery="state.ignoreQuery"
                        @change="params => handleFormItemChange(params)"
                      />
                    </el-col>
                  </el-row>
                </MerakColapse>
                <MerakColapse :is-active="false">
                  <template #header>{{ $t("staff_list.on_the_job_info") }}</template>
                  <el-row :gutter="40">
                    <el-col v-for="item of formItems.job" :span="span">
                      <MerakXFormItem
                        v-bind="item"
                        :label="$t(`staff_list.${item.prop}`)"
                        :query-options="field => queryOptions(field)"
                        v-model:value="formValue[item.prop]"
                        v-model:default="formValue[`${item.prop}_txt`]"
                        v-model:ingoreQuery="state.ignoreQuery"
                        @change="params => handleFormItemChange(params)"
                      />
                    </el-col>
                  </el-row>
                </MerakColapse>
                <MerakColapse :is-active="false">
                  <template #header>{{ $t("staff_list.contract_info") }}</template>
                  <el-row :gutter="40">
                    <template v-for="item of formItems.contract">
                      <el-col v-if="item.visible !== false" :span="span">
                        <MerakXFormItem
                          v-bind="item"
                          :label="$t(`staff_list.${item.prop}`)"
                          :query-options="field => queryOptions(field)"
                          v-model:value="formValue[item.prop]"
                          v-model:default="formValue[`${item.prop}_txt`]"
                          v-model:ingoreQuery="state.ignoreQuery"
                          @change="params => handleFormItemChange(params)"
                        />
                      </el-col>
                    </template>
                  </el-row>
                </MerakColapse>
              </el-form>
            </div>
          </el-scrollbar>
        </div>
        <div class="modal-footer">
          <el-button type="default" @click="handleReset">{{ $t("merak.reset") }}</el-button>
          <el-button type="primary" @click="handleSearch">{{ $t("merak.search") }}</el-button>
          <el-button plain type="primary" v-if="searchProp.closePlan" @click="searchRef?.showPlanModal">{{
            $t("merak.save_search_scheme")
          }}</el-button>
        </div>
      </div>
    </template>
  </SearchBar>
</template>

<script setup lang="ts">
import { getCurrentInstance, ref, reactive, computed, watch, watchEffect, onMounted } from "vue";

import { FormRules, ElButton, ElRow, ElCol, ElForm } from "element-plus";

import MerakXFormItem, {
  MerakXFormItemProps,
  MerakXFormItemOption,
  MerakXFormItemChangeParams
} from "@/components/MerakXFormItem";

import SearchBar from "@/components/SearchBar/index.vue";
import SelectedParams from "@/components/SearchBar/components/selectedParams.vue";
import MerakColapse from "@/components/merakColapse/index.vue";

import { useGlobalStore } from "@/stores/modules/global";

import { ResultEnum } from "@/enums/httpEnum";

import { UserAuthType } from "@/api/modules/user";
import { getDictOptions } from "@/api/modules/sysManage/personnel";

import { userItems, newsletterItems, educationItems, jobItems, contractItems } from "../formItems";

const currentInstance = getCurrentInstance();

const t = (message: string = "") => currentInstance?.proxy?.$t(message);

const props = defineProps<{
  auth?: UserAuthType;
  tableId?: string;
}>();

const emit = defineEmits<{
  add: [];
  fastSearch: [val: any];
  formSearch: [params: Record<string, any>];
}>();

const globalStore = useGlobalStore();

const searchRef = ref<InstanceType<typeof SearchBar>>();

const formRef = ref<InstanceType<typeof ElForm>>();

const state = reactive<{
  ignoreQuery: boolean;
  idTypeOptions: MerakXFormItemOption[];
}>({
  ignoreQuery: false,
  idTypeOptions: []
});

const formValue = reactive<Record<string, any>>({});

const jsonItems = reactive({
  user: JSON.parse(
    JSON.stringify(
      userItems.map(item => {
        if (item.prop === "constellation") {
          return { prop: item.prop, type: "select" } as MerakXFormItemProps;
        }
        return { ...item };
      })
    )
  ).filter(item => !["age", "twelve"].includes(item.prop)),
  newsletter: JSON.parse(
    JSON.stringify([
      { prop: "country_code", label: "区号", type: "select" },
      ...newsletterItems.map(item => {
        if (item.prop === "mobile") {
          return { prop: item.prop, type: "input", props: { numberType: {} } };
        }
        return { ...item };
      })
    ])
  ),
  education: JSON.parse(JSON.stringify(educationItems)),
  job: JSON.parse(
    JSON.stringify(
      jobItems.map(item => {
        if (item.prop === "org_group") {
          return { prop: "org_title", type: "select" } as MerakXFormItemProps;
        }
        return { ...item };
      })
    )
  ).filter(item => !["password", "company_seniority"].includes(item.prop)),
  contract: JSON.parse(JSON.stringify(contractItems))
});

const formRules = reactive<FormRules>({
  employee_name: [
    {
      trigger: "change",
      validator: (rule, value, callback) => {
        let reg = /[\d~`!@#$%^&*()\-_=+[\]{}|;:'",<.>/?]+/g;
        if (reg.test(value)) {
          callback(new Error(currentInstance?.proxy?.$t("staff_list.employee_name_valid_limit")));
        } else {
          callback();
        }
      }
    }
  ],
  employee_alias: [
    {
      trigger: "change",
      validator: (rule, value, callback) => {
        const reg = /[~`!@#$%^&*()\-_=+[\]{}|;:'",<.>/?]+/g;
        if (reg.test(value)) {
          callback(new Error(currentInstance?.proxy?.$t("staff_list.employee_alias_valid_limit")));
        } else {
          callback();
        }
      }
    }
  ],
  file_no: [
    {
      trigger: "change",
      validator: (rule, value, callback) => {
        const reg = /^[\w\s]*$/;
        if (!!value && !reg.test(value)) {
          callback(new Error(currentInstance?.proxy?.$t("staff_list.file_no_valid")));
        } else {
          callback();
        }
      }
    }
  ],
  id_no: [
    {
      trigger: "change",
      validator: (rule, value, callback) => {
        let reg: RegExp;
        switch (formValue.id_type) {
          case 1:
            reg = /^[1-9]\d{5}(18|19|20|21|22)?\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}(\d|[Xx])$/;
            break;
          default:
            reg = /^[A-Za-z0-9]+$/;
            break;
        }
        if (!!value && !reg.test(value)) {
          callback(new Error(currentInstance?.proxy?.$t("staff_list.id_valid")));
        } else {
          callback();
        }
      }
    }
  ],
  mobile: [
    {
      trigger: "change",
      validator: (rule, value, callback) => {
        let reg: RegExp;
        switch (formValue.country_code) {
          case 86:
            reg = /^1\d{10}$/;
            break;
          case 7:
            reg = /^\d{10}$/;
            break;
          case 375:
            reg = /^\d{9}$/;
            break;
          case 374:
            reg = /^\d{8}$/;
            break;
          default:
            reg = /^[1-9]\d*$/;
            break;
        }
        if (!!value && !reg.test(value)) {
          callback(new Error(currentInstance?.proxy?.$t("staff_list.mobile_valid_limit")));
        } else {
          callback();
        }
      }
    }
  ],
  phone_ext: [
    {
      trigger: "change",
      validator: (rule, value, callback) => {
        const reg = /^[1-9]\d*$/;
        if (!!value && !reg.test(value)) {
          callback(new Error(currentInstance?.proxy?.$t("staff_list.phone_valid")));
        } else {
          callback();
        }
      }
    }
  ],
  phone: [
    {
      trigger: "change",
      validator: (rule, value, callback) => {
        const reg = /^[1-9]\d*$/;
        if (!!value && !reg.test(value)) {
          callback(new Error(currentInstance?.proxy?.$t("staff_list.phone_valid")));
        } else {
          callback();
        }
      }
    }
  ],
  personal_email: [
    {
      trigger: "change",
      validator: (rule, value, callback) => {
        const reg =
          /^[A-Za-z0-9]+([-._][A-Za-z0-9]+)*@[A-Za-z0-9]+(-[A-Za-z0-9]+)*(\.[A-Za-z]{2,6}|[A-Za-z]{2,4}\.[A-Za-z]{2,3})$/;
        if (!!value && !reg.test(value)) {
          callback(new Error(currentInstance?.proxy?.$t("staff_list.email_valid")));
        }
        callback();
      }
    }
  ],
  company_email: [
    {
      trigger: "change",
      validator: (rule, value, callback) => {
        const reg =
          /^[A-Za-z0-9]+([-._][A-Za-z0-9]+)*@[A-Za-z0-9]+(-[A-Za-z0-9]+)*(\.[A-Za-z]{2,6}|[A-Za-z]{2,4}\.[A-Za-z]{2,3})$/;
        if (!!value && !reg.test(value)) {
          callback(new Error(currentInstance?.proxy?.$t("staff_list.email_valid")));
        }
        callback();
      }
    }
  ],
  job_no: [
    {
      trigger: "blur",
      validator: (rule, value, callback) => {
        const reg = /^[0-9]*$/;
        if (!!value && !reg.test(value)) {
          callback(new Error(currentInstance?.proxy?.$t("staff_list.integer_valid")));
        } else {
          callback();
        }
      }
    }
  ],
  username: [
    {
      trigger: "change",
      validator: (rule, value, callback) => {
        const reg = /^[\w\s]*$/;
        if (!!value && !reg.test(value)) {
          callback(new Error(currentInstance?.proxy?.$t("staff_list.username_valid_limit")));
        } else {
          callback();
        }
      }
    }
  ],
  contract_period: [
    {
      trigger: "change",
      validator: (rule, value, callback) => {
        const reg = /^\d+(\.\d{1,1})?$/;
        if (!!value) {
          if (reg.test(value)) {
            if (Math.floor(value) > 100) {
              callback(new Error(currentInstance?.proxy?.$t("staff_list.contract_period_valid_limit")));
            }
            callback();
          } else {
            callback(new Error(currentInstance?.proxy?.$t("staff_list.one_float_valid")));
          }
        }
        callback();
      }
    }
  ]
});

const formItems = computed(() => {
  return {
    user: [...jsonItems.user].map(item => {
      if (item.prop === "id_type") {
        return {
          ...item,
          options: state.idTypeOptions.filter(option =>
            formValue.nationality === "china" ? true : [0, 6].includes(option.value as number)
          )
        };
      }
      return { ...item };
    }),
    newsletter: [...jsonItems.newsletter],
    education: [...jsonItems.education],
    job: [...jsonItems.job].map(item => {
      return { ...item };
    }),
    contract: [...jsonItems.contract].map(item => {
      if (["contract_period", "contract_end"].includes(item.prop)) {
        return { ...item, visible: formValue.contract_type !== 3 };
      }
      return { ...item };
    })
  };
});

const formData = computed({
  get: () => {
    const items: MerakXFormItemProps[] = [
      ...formItems.value.user,
      ...formItems.value.newsletter,
      ...formItems.value.education,
      ...formItems.value.job,
      ...formItems.value.contract
    ];
    const data: Record<string, Record<string, any>> = {};
    for (let item of items) {
      data[item.prop] = {
        label: t(`staff_list.${item.prop}`),
        value: formValue[item.prop],
        type: item.type,
        props: { ...(item.props ?? {}) },
        options: [...(item.options ?? [])]
      };
    }
    return data;
  },
  set: value => {
    for (let [key, item] of Object.entries(value)) {
      formValue[key] = item.value;
    }
  }
});

const span = computed(() => (globalStore.language === "ru" ? 8 : 6));

const queryOptions = async (key?: string) => {
  if (!key) return;
  return getDictOptions({ key }).then(({ code, data }) => {
    if (code == ResultEnum.SUCCESS) {
      const options = [...data].map(item => ({ value: item.key, label: item.value }));
      for (let items of Object.values(jsonItems)) {
        if (items.some(item => item.prop === key)) {
          items.forEach(item => {
            if (item.prop === key) {
              item.options = options;
            }
          });
        }
      }
      return options;
    }
    return;
  });
};

const handleFormItemChange = (params: MerakXFormItemChangeParams) => {
  switch (params.type) {
    case "input":
      if (!!params.data) {
        formValue[params.prop] = params.data.trim();
      }
      break;
    default:
      break;
  }
};

const handleSearchEvent = (val: {
  action?: "enter" | "plan" | "form";
  params?: Record<string, any>;
  plan?: string | number;
  search?: string;
}) => {
	console.log(jsonItems)
  if (val.action === "plan" && !!val.params) {
    state.ignoreQuery = false;
    for (let key of Object.keys(formValue)) {
      formValue[key] = undefined;
    }
    for (let key of Object.keys(val.params)) {
      if (!key.includes("_options")) {
        formValue[key] = val.params[key];
      } else if (Array.isArray(val.params[key]) && !!val.params[key].length) {
        const field = key.split("_options")?.[0];
        for (let items of Object.values(jsonItems)) {
          if (items.some(item => item.prop === field)) {
            items.forEach(item => {
              if (item.prop === field) {
                item.options = val.params![key];
              }
            });
          }
        }
      }
    }
  }
  emit("fastSearch", val);
};

const handleSearch = () => {
  formRef.value?.validate(valid => {
    if (valid) {
      const params = searchRef.value?.formParams("value");
      if (!!params) {
        emit("formSearch", params);
      }
      searchRef.value?.clear();
      searchRef.value?.modalHide();
    }
  });
};

const handleReset = () => {
  for (let key of Object.keys(formValue)) {
    formValue[key] = undefined;
  }
  formRef.value?.clearValidate();
  searchRef.value?.clear();
  const timer = requestAnimationFrame(() => {
    const params = searchRef.value?.formParams("value");
    if (!!params) {
      emit("formSearch", params);
    }
    cancelAnimationFrame(timer);
  });
};

// 合同类型联动;
watch(
  () => formValue.contract_type,
  () => {
    if (formValue.contract_type === 3) {
      delete formValue.contract_period;
    }
  }
);

watchEffect(() => {
  if (!!props.tableId) {
    searchRef.value?.getPlanList(props.tableId);
  }
});

onMounted(() => {
  // queryOptions("id_type").then(data => {
  //   state.idTypeOptions = [...(data ?? [])];
  // });
});
</script>

<style scoped lang="scss">
.el-form-item {
  :deep(.el-form-item__content > *) {
    width: 100%;
  }
}
</style>
